package uk.ac.qub.midorfeed;

import java.util.ArrayList;
import java.util.List;
import uk.ac.qub.midorfeed.R;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;

/**
 * Class representing main functionality of app
 * 
 * @author Graeme
 * 
 */
public class TeamPickerActivity extends Activity {

	/**
	 * ArrayList of heroes used to populate widgets - set via the
	 * poplateHeroes() method in HeroManager class
	 */
	final ArrayList<Hero> heroesArray = HeroManager.populateHeroes();

	/**
	 * List to hold suggested heroes from server
	 */
	public static ArrayList<Hero> suggestedHeroes;

	/**
	 * Spinners used for selecting friendly hero picks
	 */
	private Spinner friendlyHero1, friendlyHero2, friendlyHero3, friendlyHero4,
			friendlyHero5;
	/**
	 * Spinners used for enemy hero picks
	 */
	private Spinner enemyHero1, enemyHero2, enemyHero3, enemyHero4, enemyHero5;

	/**
	 * List used to contain selected friendly hero picks
	 */
	private List<Hero> friendlyHeroes = new ArrayList<Hero>(5);
	/**
	 * List used to contain selected enemy hero picks
	 */
	private List<Hero> enemyHeroes = new ArrayList<Hero>(5);
	/**
	 * String message to be displayed if hero has already been selected
	 */
	private String heroError = "That hero has already been selected :(";

	/**
	 * Used to play the background sound for the activity
	 */
	private MediaPlayer backgroundPlayer;

	/**
	 * On create method
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_team_picker);
		// Show the Up button in the action bar.
		getAssets();

		// adding placeholder objects to friendly/enemy hero lists to prevent
		// out of bounds exceptions
		friendlyHeroes.add(0, heroesArray.get(0));
		friendlyHeroes.add(1, heroesArray.get(0));
		friendlyHeroes.add(2, heroesArray.get(0));
		friendlyHeroes.add(3, heroesArray.get(0));
		friendlyHeroes.add(4, heroesArray.get(0));

		enemyHeroes.add(0, heroesArray.get(0));
		enemyHeroes.add(1, heroesArray.get(0));
		enemyHeroes.add(2, heroesArray.get(0));
		enemyHeroes.add(3, heroesArray.get(0));
		enemyHeroes.add(4, heroesArray.get(0));
		// intialises background sound player
		initialiseMediaPlayer();
		// sets the various listeners used for selecting heroes
		setFriendlyHeroOneListener();
		setFriendlyHeroTwoListener();
		setFriendlyHeroThreeListener();
		setFriendlyHeroFourListener();
		setFriendlyHeroFiveListener();

		setEnemyHeroOneListener();
		setEnemyHeroTwoListener();
		setEnemyHeroThreeListener();
		setEnemyHeroFourListener();
		setEnemyHeroFiveListener();
		// sets listeners for the pick team/clear team buttons
		setPickTeamButtonListener();
		setClearTeamsButtonListener();
	}

	/**
	 * On start method
	 */
	@Override
	public void onStart() {
		super.onStart();
		if (StartScreenActivity.playSound) {// starts background sound
			backgroundPlayer.start();
		}
	}

	/**
	 * On pause method
	 */
	@Override
	public void onPause() {

		super.onPause();
		if (backgroundPlayer != null) {
			backgroundPlayer.stop();// stops background music & releases object
			backgroundPlayer = null;
		}
	}

	/**
	 * on stop method
	 */
	@Override
	public void onStop() {

		super.onStop();
		// stops and releases the background sound player
		if (backgroundPlayer != null) {
			backgroundPlayer.stop();
			backgroundPlayer = null;
		}
	}

	/**
	 * On resume method
	 */
	@Override
	public void onResume() {
		super.onResume();
		initialiseMediaPlayer();// Initialises and starts background sound
		if (StartScreenActivity.playSound) {
			backgroundPlayer.start();
		}
	}

	/**
	 * On restart method
	 */
	@Override
	public void onRestart() {
		super.onRestart();
		initialiseMediaPlayer();// Initialises and starts background sound
		if (StartScreenActivity.playSound) {
			backgroundPlayer.start();
		}
	}

	/**
	 * Private method to set pick team button listener
	 */
	private void setPickTeamButtonListener() {

		Button pickTeamBtn = (Button) findViewById(R.id.pick_team_button);
		pickTeamBtn.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// checks if there is a network connection available
				if (HttpUtils.isConnected(TeamPickerActivity.this)) {
					// creates hero suggester object
					HeroSuggester suggester = new HeroSuggester(
							TeamPickerActivity.this);
					// passes in selected friendly/enemy hero lists for
					// processing
					suggester.setOurHeroes(friendlyHeroes);
					suggester.setEnemyHeroes(enemyHeroes);
					// executes as an asynctask so that it runs in background
					suggester.execute();

				} else {
					Toast.makeText(TeamPickerActivity.this,
							"Network connection required to get suggestion.",// printed
																				// to
																				// screen
																				// if
																				// theres
																				// no
																				// connection
							Toast.LENGTH_SHORT).show();
				}
			}
		});
	}

	/**
	 * Private method to set up clear heroes selected button
	 */
	private void setClearTeamsButtonListener() {

		Button clearTeamsBtn = (Button) findViewById(R.id.clear_teams_button);
		clearTeamsBtn.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {

				for (int loop = 0; loop < 5; loop++) {
					// sets the selected heroes back to place holders in the
					// corresponding lists
					friendlyHeroes.set(loop, heroesArray.get(0));
					enemyHeroes.set(loop, heroesArray.get(0));
				}
				// sets the spinners back to their default position
				friendlyHero1.setSelection(0);
				friendlyHero2.setSelection(0);
				friendlyHero3.setSelection(0);
				friendlyHero4.setSelection(0);
				friendlyHero5.setSelection(0);

				enemyHero1.setSelection(0);
				enemyHero2.setSelection(0);
				enemyHero3.setSelection(0);
				enemyHero4.setSelection(0);
				enemyHero5.setSelection(0);

			}
		});

	}

	/**
	 * Private method to set up friendly hero 1 spinner
	 */
	private void setFriendlyHeroOneListener() {

		friendlyHero1 = (Spinner) findViewById(R.id.friendly_hero_one);
		friendlyHero1.setAdapter(new HeroAdapter(this, R.layout.hero_spinner,
				heroesArray));// sets adaptor to HeroAdaptor defined below

		friendlyHero1.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				// creates hero object from the item selected in the spinner
				Hero hero = (Hero) parent.getAdapter().getItem(position);
				// checks to see if hero has already been selected
				if (position != 0 && !friendlyHeroes.contains(hero)
						&& !enemyHeroes.contains(hero)) {
					// if unselected, calls playHeroSound() method, removes the
					// placeholder from the corresponding position and inserts
					// selected hero
					playHeroSound(hero);
					friendlyHeroes.remove(0);
					friendlyHeroes.add(0, hero);
					// displays a toast message if hero is already selected
					// (checks position!=0 as position 0 is a placeholder)
				} else if (position != 0) {
					Toast.makeText(TeamPickerActivity.this, heroError,
							Toast.LENGTH_SHORT).show();
					friendlyHero1.setSelection(0);
				}
			}

			// shoudl not be displayed
			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				String spinnerValue = "An error has occurred";
				Toast.makeText(TeamPickerActivity.this, spinnerValue,
						Toast.LENGTH_SHORT).show();
			}
		});

	}

	/**
	 * Private method to set up friendly hero 2 spinner
	 */
	private void setFriendlyHeroTwoListener() {

		friendlyHero2 = (Spinner) findViewById(R.id.friendly_hero_two);
		friendlyHero2.setAdapter(new HeroAdapter(this, R.layout.hero_spinner,
				heroesArray));// sets adaptor to HeroAdaptor defined below

		friendlyHero2.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				// creates hero object from the item selected in the spinner
				Hero hero = (Hero) parent.getAdapter().getItem(position);
				// checks to see if hero has already been selected
				if (position != 0 && !friendlyHeroes.contains(hero)
						&& !enemyHeroes.contains(hero)) {
					// if unselected, calls playHeroSound() method, removes the
					// placeholder from the corresponding position and inserts
					// selected hero
					playHeroSound(hero);
					friendlyHeroes.remove(1);
					friendlyHeroes.add(1, hero);
					// displays a toast message if hero is already selected
					// (checks position!=0 as position 0 is a placeholder)
				} else if (position != 0) {
					Toast.makeText(TeamPickerActivity.this, heroError,
							Toast.LENGTH_SHORT).show();
					friendlyHero2.setSelection(0);
				}
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				String spinnerValue = "An error has occurred";
				Toast.makeText(TeamPickerActivity.this, spinnerValue,
						Toast.LENGTH_SHORT).show();
			}
		});

	}

	/**
	 * Private method to set up friendly hero 3 spinner
	 */
	private void setFriendlyHeroThreeListener() {

		friendlyHero3 = (Spinner) findViewById(R.id.friendly_hero_three);
		friendlyHero3.setAdapter(new HeroAdapter(this, R.layout.hero_spinner,
				heroesArray));// sets adaptor to HeroAdaptor defined below

		friendlyHero3.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				// creates hero object from the item selected in the spinner
				Hero hero = (Hero) parent.getAdapter().getItem(position);
				// checks to see if hero has already been selected
				if (position != 0 && !friendlyHeroes.contains(hero)
						&& !enemyHeroes.contains(hero)) {
					// if unselected, calls playHeroSound() method, removes the
					// placeholder from the corresponding position and inserts
					// selected hero
					playHeroSound(hero);
					friendlyHeroes.remove(2);
					friendlyHeroes.add(2, hero);
					// displays a toast message if hero is already selected
					// (checks position!=0 as position 0 is a placeholder)
				} else if (position != 0) {
					Toast.makeText(TeamPickerActivity.this, heroError,
							Toast.LENGTH_SHORT).show();
					friendlyHero3.setSelection(0);
				}
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				String spinnerValue = "An error has occurred";
				Toast.makeText(TeamPickerActivity.this, spinnerValue,
						Toast.LENGTH_SHORT).show();
			}
		});
	}

	/**
	 * Private method to set friendly hero 4 spinner
	 */
	private void setFriendlyHeroFourListener() {

		friendlyHero4 = (Spinner) findViewById(R.id.friendly_hero_four);
		friendlyHero4.setAdapter(new HeroAdapter(this, R.layout.hero_spinner,
				heroesArray));// sets adaptor to HeroAdaptor defined below

		friendlyHero4.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				// creates hero object from the item selected in the spinner
				Hero hero = (Hero) parent.getAdapter().getItem(position);
				// checks to see if hero has already been selected
				if (position != 0 && !friendlyHeroes.contains(hero)
						&& !enemyHeroes.contains(hero)) {
					// if unselected, calls playHeroSound() method, removes the
					// placeholder from the corresponding position and inserts
					// selected hero
					playHeroSound(hero);
					friendlyHeroes.remove(3);
					friendlyHeroes.add(3, hero);
					// displays a toast message if hero is already selected
					// (checks position!=0 as position 0 is a placeholder)
				} else if (position != 0) {
					Toast.makeText(TeamPickerActivity.this, heroError,
							Toast.LENGTH_SHORT).show();
					friendlyHero4.setSelection(0);
				}
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				String spinnerValue = "An error has occurred";
				Toast.makeText(TeamPickerActivity.this, spinnerValue,
						Toast.LENGTH_SHORT).show();
			}
		});
	}

	/**
	 * Method to set up friendly hero 5 spinner
	 */
	private void setFriendlyHeroFiveListener() {

		friendlyHero5 = (Spinner) findViewById(R.id.friendly_hero_five);
		friendlyHero5.setAdapter(new HeroAdapter(this, R.layout.hero_spinner,
				heroesArray));// sets adaptor to HeroAdaptor defined below

		friendlyHero5.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				// creates hero object from the item selected in the spinner
				Hero hero = (Hero) parent.getAdapter().getItem(position);
				// (checks position!=0 as position 0 is a placeholder)
				if (position != 0 && !friendlyHeroes.contains(hero)
						&& !enemyHeroes.contains(hero)) {
					// if unselected, calls playHeroSound() method, removes the
					// placeholder from the corresponding position and inserts
					// selected hero
					playHeroSound(hero);
					friendlyHeroes.remove(4);
					friendlyHeroes.add(4, hero);
					// displays a toast message if hero is already selected
				} else if (position != 0) {
					Toast.makeText(TeamPickerActivity.this, heroError,
							Toast.LENGTH_SHORT).show();
					friendlyHero5.setSelection(0);
				}
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				String spinnerValue = "An error has occurred";
				Toast.makeText(TeamPickerActivity.this, spinnerValue,
						Toast.LENGTH_SHORT).show();
			}
		});
	}

	/**
	 * Private method to set up enemy hero 1 spinner
	 */
	private void setEnemyHeroOneListener() {

		enemyHero1 = (Spinner) findViewById(R.id.enemy_hero_one);
		enemyHero1.setAdapter(new HeroAdapter(this, R.layout.hero_spinner,
				heroesArray));// sets adaptor to HeroAdaptor defined below

		enemyHero1.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				// creates hero object from the item selected in the spinner
				Hero hero = (Hero) parent.getAdapter().getItem(position);
				// (checks position!=0 as position 0 is a placeholder)
				if (position != 0 && !friendlyHeroes.contains(hero)
						&& !enemyHeroes.contains(hero)) {
					// if unselected, calls playHeroSound() method, removes the
					// placeholder from the corresponding position and inserts
					// selected hero
					playHeroSound(hero);
					enemyHeroes.remove(0);
					enemyHeroes.add(0, hero);
					// displays a toast message if hero is already selected
				} else if (position != 0) {
					Toast.makeText(TeamPickerActivity.this, heroError,
							Toast.LENGTH_SHORT).show();
					enemyHero1.setSelection(0);
				}
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				String spinnerValue = "An error has occurred";
				Toast.makeText(TeamPickerActivity.this, spinnerValue,
						Toast.LENGTH_SHORT).show();
			}
		});
	}

	/**
	 * private method to set up enemy hero 2 spinner
	 */
	private void setEnemyHeroTwoListener() {
		enemyHero2 = (Spinner) findViewById(R.id.enemy_hero_two);
		enemyHero2.setAdapter(new HeroAdapter(this, R.layout.hero_spinner,
				heroesArray));// sets adaptor to HeroAdaptor defined below

		enemyHero2.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				// creates hero object from the item selected in the spinner
				Hero hero = (Hero) parent.getAdapter().getItem(position);
				// (checks position!=0 as position 0 is a placeholder)
				if (position != 0 && !friendlyHeroes.contains(hero)
						&& !enemyHeroes.contains(hero)) {
					// if unselected, calls playHeroSound() method, removes the
					// placeholder from the corresponding position and inserts
					// selected hero
					playHeroSound(hero);
					enemyHeroes.remove(1);
					enemyHeroes.add(1, hero);
					// displays a toast message if hero is already selected
				} else if (position != 0) {
					Toast.makeText(TeamPickerActivity.this, heroError,
							Toast.LENGTH_SHORT).show();
					enemyHero2.setSelection(0);
				}
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				String spinnerValue = "An error has occurred";
				Toast.makeText(TeamPickerActivity.this, spinnerValue,
						Toast.LENGTH_SHORT).show();
			}
		});
	}

	/**
	 * Private method to set up enemy hero 3 spinner
	 */
	private void setEnemyHeroThreeListener() {
		enemyHero3 = (Spinner) findViewById(R.id.enemy_hero_three);
		enemyHero3.setAdapter(new HeroAdapter(this, R.layout.hero_spinner,
				heroesArray));

		enemyHero3.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				// creates hero object from the item selected in the spinner
				Hero hero = (Hero) parent.getItemAtPosition(position);
				// (checks position!=0 as position 0 is a placeholder)
				if (position != 0 && !friendlyHeroes.contains(hero)
						&& !enemyHeroes.contains(hero)) {
					// if unselected, calls playHeroSound() method, removes the
					// placeholder from the corresponding position and inserts
					// selected hero
					playHeroSound(hero);
					enemyHeroes.remove(2);
					enemyHeroes.add(2, hero);
					// displays a toast message if hero is already selected
				} else if (position != 0) {
					Toast.makeText(TeamPickerActivity.this, heroError,
							Toast.LENGTH_SHORT).show();
					enemyHero3.setSelection(0);
				}
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				String spinnerValue = "An error has occurred";
				Toast.makeText(TeamPickerActivity.this, spinnerValue,
						Toast.LENGTH_SHORT).show();
			}
		});
	}

	/**
	 * Private method to set up enemy hero 4 spinner
	 */
	private void setEnemyHeroFourListener() {
		enemyHero4 = (Spinner) findViewById(R.id.enemy_hero_four);
		enemyHero4.setAdapter(new HeroAdapter(this, R.layout.hero_spinner,
				heroesArray));

		enemyHero4.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				// creates hero object from the item selected in the spinner
				Hero hero = (Hero) parent.getAdapter().getItem(position);
				// (checks position!=0 as position 0 is a placeholder)
				if (position != 0 && !friendlyHeroes.contains(hero)
						&& !enemyHeroes.contains(hero)) {
					// if unselected, calls playHeroSound() method, removes the
					// placeholder from the corresponding position and inserts
					// selected hero
					playHeroSound(hero);
					enemyHeroes.remove(3);
					enemyHeroes.add(3, hero);
					// displays a toast message if hero is already selected
				} else if (position != 0) {
					Toast.makeText(TeamPickerActivity.this, heroError,
							Toast.LENGTH_SHORT).show();
					enemyHero4.setSelection(0);
				}
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				String spinnerValue = "An error has occurred";
				Toast.makeText(TeamPickerActivity.this, spinnerValue,
						Toast.LENGTH_SHORT).show();
			}
		});
	}

	/**
	 * Private method to set up enemy hero 5 listener
	 */
	private void setEnemyHeroFiveListener() {
		enemyHero5 = (Spinner) findViewById(R.id.enemy_hero_five);
		enemyHero5.setAdapter(new HeroAdapter(this, R.layout.hero_spinner,
				heroesArray));

		enemyHero5.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				// creates hero object from the item selected in the spinner
				Hero hero = (Hero) parent.getAdapter().getItem(position);
				// (checks position!=0 as position 0 is a placeholder)
				if (position != 0 && !friendlyHeroes.contains(hero)
						&& !enemyHeroes.contains(hero)) {
					// if unselected, calls playHeroSound() method, removes the
					// placeholder from the corresponding position and inserts
					// selected hero
					playHeroSound(hero);
					enemyHeroes.remove(4);
					enemyHeroes.add(4, hero);
					// displays a toast message if hero is already selected
				} else if (position != 0) {
					Toast.makeText(TeamPickerActivity.this, heroError,
							Toast.LENGTH_SHORT).show();
					enemyHero5.setSelection(0);
				}
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				String spinnerValue = "An error has occurred";
				Toast.makeText(TeamPickerActivity.this, spinnerValue,
						Toast.LENGTH_SHORT).show();
			}
		});

	}

	/**
	 * Set up the {@link android.app.ActionBar}, if the API is available.
	 */
	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	private void setupActionBar() {
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
			getActionBar().setDisplayHomeAsUpEnabled(true);
		}
	}

	/**
	 * Method to initialise the media player
	 */
	public void initialiseMediaPlayer() {
		if (backgroundPlayer == null) {
			backgroundPlayer = MediaPlayer.create(this, R.raw.hero_pick_music);// creates
																				// object,
																				// sets
																				// it
																				// to
																				// background
																				// music
			backgroundPlayer.setLooping(true);
		}
	}

	/**
	 * Method to play corresponding hero sound when called
	 * 
	 * @param hero
	 *            - Hero object whose sound you wish to play
	 */
	public void playHeroSound(Hero hero) {
		// creates mediaplayer object, passing in context and the int value of
		// sound location in res/raw
		MediaPlayer heroSounds = MediaPlayer.create(this, hero.getHeroSound());
		// if statement to check if there is another hero sound playing and if
		// so stops it

		if (heroSounds.isPlaying()) {
			heroSounds.stop();
			heroSounds.reset();
		}
		if (StartScreenActivity.playSound) {
			heroSounds.start();
		}
	}

	/**
	 * Class to be used when adapting hero spinner widgets to custom layout &
	 * hero list
	 * 
	 * @author Graeme
	 * 
	 */
	public class HeroAdapter extends ArrayAdapter<Hero> {

		private ArrayList<Hero> heroArray = new ArrayList<Hero>();

		/**
		 * Constructor for adapter
		 * 
		 * @param context
		 *            - context of activity using
		 * @param resource
		 *            - Layout XML you wish to adapt to
		 * @param objects
		 *            - List <Hero>
		 */
		public HeroAdapter(Context context, int resource, List<Hero> objects) {
			super(context, resource, objects);
			heroArray.addAll(objects);
		}

		/**
		 * Method to get drop down view for widget
		 */
		@Override
		public View getDropDownView(int position, View convertView,
				ViewGroup parent) {
			return getCustomView(position, convertView, parent);
		}

		/**
		 * returns view of adapter
		 */
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			return getCustomView(position, convertView, parent);
		}

		/**
		 * Sets the custom view of widget
		 * 
		 * @param position
		 *            - Position in list
		 * @param convertView
		 * @param parent
		 * @return - Adapted view
		 */
		public View getCustomView(int position, View convertView,
				ViewGroup parent) {

			LayoutInflater inflater = getLayoutInflater();
			// inflates view
			View heroView = inflater.inflate(R.layout.hero_spinner, parent,
					false);
			// sets the element in the widget to the corresponding hero name and
			// hero image
			TextView heroName = (TextView) heroView
					.findViewById(R.id.hero_names);
			heroName.setText(heroArray.get(position).toString());

			ImageView heroImage = (ImageView) heroView
					.findViewById(R.id.hero_image);
			heroImage.setImageResource(heroArray.get(position).getHeroImage());

			return heroView;

		}
	}

	/**
	 * Class to execute an asynchronous task sending a request to the server to
	 * obtain suggested heroes depending on current picks.
	 * 
	 * @author graeme
	 */
	public class HeroSuggester extends AsyncTask<String, Void, String> {
		/**
		 * The URL exposed by the server to perform the suggestion remotely.
		 */
		private static final String REQUEST_URL = "http://37.122.208.94:5000/api/suggest/";

		/**
		 * list of heroes selected by the user.
		 */
		private List<Hero> friendlyHeroes;

		/**
		 * list of enemy heroes selected by the user.
		 */
		private List<Hero> enemyHeroes;

		/**
		 * Android context used to perform operations depending on the current
		 * activity etc.
		 */
		private Context context;

		/**
		 * Constructs an instance of the hero suggester. We pass the context
		 * from the calling activity.
		 * 
		 * @param context
		 *            context of the calling activity.
		 */
		public HeroSuggester(Context context) {
			this.context = context;
		}

		/**
		 * Method performed in background as a asynchronous task
		 * 
		 * @Return Suggested heroes from the server in a string format
		 * @param args
		 *            not used.
		 */
		@Override
		protected String doInBackground(final String... args) {
			String serverResponse = null;

			if (friendlyHeroes != null || enemyHeroes != null
					|| friendlyHeroes.size() > 0 || enemyHeroes.size() > 0) {

				final String requestParameters = buildRequestParameters();

				serverResponse = HttpUtils.getResponse(REQUEST_URL,
						requestParameters);
			} else {
				Log.e("HS",
						"Cannot retrieve suggestion with an invalid hero selection.");
			}

			return serverResponse;
		}

		/**
		 * Receives the String result from the doInBackground method and parses
		 * it to be displayed as a dialog box
		 */
		@Override
		protected void onPostExecute(String result) {
			TeamPickerActivity.suggestedHeroes = new ArrayList<Hero>(
					parseResult(result));
			showSuggestedHeroesDialog();

		}

		/**
		 * Method to convert the list of heroes to a format readable by the
		 * server.
		 * 
		 * @return string representing heroes in a server readable format.
		 */
		private String buildRequestParameters() {
			final StringBuffer stringBuffer = new StringBuffer("?");
			// x= being friendly heroes selected
			stringBuffer.append("x=");

			for (final Hero friendlyHero : friendlyHeroes) {
				// adds IDs of friendly heroes chosen
				if (friendlyHero.getHeroID() != 0) {
					stringBuffer.append(friendlyHero.getHeroID());
					stringBuffer.append(",");
				}
			}

			stringBuffer.deleteCharAt(stringBuffer.length() - 1);
			// y= being the enemy team selected
			stringBuffer.append("&y=");

			for (final Hero enemyHero : enemyHeroes) {
				// adds IDs of enemy heroes chosen
				if (enemyHero.getHeroID() != 0) {
					stringBuffer.append(enemyHero.getHeroID());
					stringBuffer.append(",");
				}
			}

			stringBuffer.deleteCharAt(stringBuffer.length() - 1);

			return stringBuffer.toString();
		}

		/**
		 * method to parses result returned to extract the hero IDs of suggested
		 * heroes
		 * 
		 * @param result
		 *            - String result produced by the doInBackground method
		 * @return - int[] of hero IDs
		 */
		private List<Hero> parseResult(String result) {

			int[] heroIDs;
			List<Hero> suggestedHeroes;

			int left = result.indexOf("[");
			int right = result.indexOf("]");
			// snips the string returned from the server so that it only
			// contains hero IDs
			String resultSubstring = result.substring(left + 1, right);
			// Splits the IDs up to enable them to be parsed
			String[] heroIDStrings = resultSubstring.split(",");
			// int[]to contain parsed hero IDs
			heroIDs = new int[heroIDStrings.length];

			for (int loop = 0; loop < heroIDStrings.length; loop++) {
				// removes any white space
				if (loop == 0) {
					heroIDStrings[loop] = heroIDStrings[loop].substring(1,
							heroIDStrings[loop].length() - 1);
				} else {
					heroIDStrings[loop] = heroIDStrings[loop].substring(2,
							heroIDStrings[loop].length() - 1);
				}
				heroIDs[loop] = Integer.parseInt(heroIDStrings[loop]);// parses
																		// the
																		// int
																		// and
																		// adds
																		// it to
																		// the
																		// int[]
			}

			suggestedHeroes = new ArrayList<Hero>(
					HeroManager.findHeroesByID(heroIDs));// calls the
															// findHeroesByID to
															// return a list of
															// hero objects
															// based on parsed
															// IDs

			return suggestedHeroes;
		}

		/**
		 * Method to set friendly heroes
		 * 
		 * @param friendlyHeroes
		 *            - List of friendly heroes selected by user
		 */
		public void setOurHeroes(final List<Hero> friendlyHeroes) {
			this.friendlyHeroes = friendlyHeroes;
		}

		/**
		 * method to set enemy heroes
		 * 
		 * @param enemyHeroes
		 *            - List of enemy heroes selected by user
		 */
		public void setEnemyHeroes(final List<Hero> enemyHeroes) {
			this.enemyHeroes = enemyHeroes;
		}
	}

	/**
	 * method to show a dialog box containing suggested heroes
	 */
	protected void showSuggestedHeroesDialog() {

		final Dialog suggestedHeroesDialog;
		final ListView suggestedHeroList;
		final Button returnBtn;

		suggestedHeroesDialog = new Dialog(TeamPickerActivity.this);

		suggestedHeroesDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
		suggestedHeroesDialog
				.setContentView(R.layout.activity_suggested_heroes_dialog);

		suggestedHeroList = (ListView) suggestedHeroesDialog
				.findViewById(R.id.suggested_heroes_dialog_listview);
		suggestedHeroList.setAdapter(new HeroAdapter(this,
				R.layout.suggested_heroes_listview,
				TeamPickerActivity.suggestedHeroes));

		returnBtn = (Button) suggestedHeroesDialog
				.findViewById(R.id.suggested_heroes_return_btn);
		returnBtn.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				suggestedHeroesDialog.dismiss();
			}
		});

		suggestedHeroesDialog.show();

	}

}
